#ifndef STRING2NUM_H
#define STRING2NUM_H

#include "Platform.h"
#include <cmath>
#include <memory>

class String2Num
{
private:
    pLib::stack<char> integerPart;
    pLib::queue<char> decimalPart;
    bool withDot = false;
    bool parsed = false;
    double result = 0;
    bool error = false;
    static constexpr inline bool isNumChar(char c) { return ((c >= '0') && (c <= '9')); }
    static constexpr inline bool isDot(char c) { return c == '.'; }
    inline double Parse()
    {
        parsed = true;
        result = 0;
        for(int i = 0; !integerPart.empty(); i++, integerPart.pop())
            result += (integerPart.top() - '0') * pow(10, i);
        if (!withDot)
            return result;
        for(int i = 1; !decimalPart.empty(); i++, decimalPart.pop())
            result += (decimalPart.front() - '0') * pow(0.1, i);
        return result;
    }

public:
    inline void Clean()
    {
        pLib::stack<char>().swap(integerPart);
        pLib::queue<char>().swap(decimalPart);
        withDot = false;
        parsed = false;
        error = false;
    }
    void operator<< (char c);
    inline void Push(char c) { operator<<(c); }
    inline void SetString(const std::string& s)
    {
        for(auto i : s)
        {
            Push(i);
            if(error) break;
        }
    }
    inline double GetResult() { return error ? 0 : parsed ? result : Parse(); }
    [[nodiscard]] inline bool IsError() const { return error; }
};


#endif //STRING2NUM_H
